<template>
  <div v-loading="loading" element-loading-text="拼命加载中"
       element-loading-spinner="el-icon-loading"
       element-loading-background="rgba(0, 0, 0, 0.8)">
    <h2 style="text-align: center">{{ name }}</h2>
    <vue-office-docx
        v-if="type === 'docx' || type === 'doc'"
        :src="fileBlob"
        style="height: 100vh;"
        @rendered="renderedHandler"
        @error="errorHandler"
    />
    <vue-office-pdf
        :staticFileUrl="''"
        v-if="type === 'pdf'"
        :src="fileBlob"
        style="height: 100vh;"
        @rendered="renderedHandler"
        @error="errorHandler"
    />
    <vue-office-excel
        v-if="type === 'xlsx'"
        :src="fileBlob"
        style="height: 100vh;"
        @rendered="renderedHandler"
        @error="errorHandler"
    />
    <div v-if="type === 'xls'">
      <div id="table">
        <el-table :data="excelData" border stripe
                  :header-cell-style="{'background':'#F5F4F7'}">
          <el-table-column
              type="index"
              label="序号"
              width="60"
              :resizable="false"
              align="center"/>
          <el-table-column
              v-for="(value, key, index) in excelData[maxIndex]"
              :key="index"
              :prop="key"
              :label="key"></el-table-column>
        </el-table>
      </div>
    </div>

    <div v-if="type === 'img'" style="width: 100%; text-align: center">
      <el-image style="max-width: 800px; max-height: 1080px"
                :src="fileBlob"
                :preview-src-list="[fileBlob]">
      </el-image>
    </div>

    <div v-if="type === 'txt'" style="width: 100%;">
      <el-form style="padding: 0 20px">
        <el-form-item label="请选择编码:">
          <el-select clearable v-model="txtDecode" size="small" style="width:200px" @change="changeTxtDecode">
            <el-option label="utf-8" value="utf-8"></el-option>
            <el-option label="gbk" value="gbk"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="内容预览:">
          <el-input type="textarea" autosize v-model="fileBlob" readonly></el-input>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import {defineComponent, onMounted, ref} from 'vue';
import VueOfficeDocx from '@vue-office/docx';
import VueOfficePdf from '@vue-office/pdf';
import VueOfficeExcel from '@vue-office/excel';
import '@vue-office/docx/lib/index.css';
import '@vue-office/excel/lib/index.css';
import * as XLSX from "xlsx";
import SysFileAPI from '@/api/sysFile/index';

export default defineComponent({
  components: {
    VueOfficeDocx, VueOfficePdf, VueOfficeExcel
  },
  setup() {
    const type = ref('');
    const fileId = ref('');
    const fileBlob = ref("");
    const loading = ref(true);
    const name = ref('');
    const txtDecode = ref('utf-8');
    const excelData = ref([]);
    const maxIndex = ref(0);

    const changeTxtDecode = () => {
      loadFile('txt');
    };

    const loadFile = (suffix: string) => {
      let imageType = ['xbm', 'tif', 'pjp', 'svgz', 'jpg', 'jpeg', 'ico', 'tiff', 'gif', 'svg', 'jfif', 'webp', 'png', 'bmp', 'pjpeg', 'avif'];
      if (imageType.includes(suffix)) {
        type.value = "img";
      }
      SysFileAPI.download("downloadPersonalFile", {"fileId": fileId.value, "noAutoDownload": '1'}).then(response => {
        if (response) {
          const blob = new Blob([response.data]);
          if (imageType.includes(suffix)) {
            const objectURL = URL.createObjectURL(blob);
            fileBlob.value = objectURL;
            renderedHandler();
          } else if (suffix === 'txt') {
            const reader = new FileReader();
            reader.readAsText(blob, txtDecode.value);
            reader.onload = () => {
              fileBlob.value = reader.result as string;
              renderedHandler();
            };
          } else {
            fileBlob.value = blob;
          }
        }
      });
    };

    const showError = () => {
      window.alert('文件格式识别失败，将以文本形式展示！');
      type.value = 'txt'
      loadFile('txt');
    };

    var workbook: any = undefined;
    const readWorkbookFromRemoteFile = () => {
      SysFileAPI.download("downloadPersonalFile", {
        "fileId": fileId.value,
        "noAutoDownload": '1'
      }, 'arraybuffer').then(response => {
        if (response) {
          const data = new Uint8Array(response.data);
          workbook = XLSX.read(data, {type: "array"});
          const sheetNames = workbook.SheetNames; // 工作表名称集合
          getTable(sheetNames[0]);
          renderedHandler();
        } else {
          errorHandler();
        }
      });
    };

    const getTable = (sheetName: string) => {
      const worksheet = workbook.Sheets[sheetName];
      excelData.value = XLSX.utils.sheet_to_json(worksheet);
      //取数组对象中，对象的key最长的一个进行赋值操作
      let arrLengths = excelData.value.map(obj => Object.keys(obj).length);
      maxIndex.value = arrLengths.indexOf(Math.max(...arrLengths));
    };

    const renderedHandler = () => {
      loading.value = false;
    };

    const errorHandler = () => {
      loading.value = false;
      console.error("加载失败，请重试！");
    };

    onMounted(() => {
      let url: string = window.location.href;
      url = url.split("?")[1];
      let urlArr: string[] = url.split("&");
      fileId.value = urlArr[0].split("=")[1];
      name.value = decodeURIComponent(urlArr[1].split("=")[1]);

      if (name.value.indexOf(".") === -1) {
        showError();
        return;
      }
      if (name.value.endsWith(".")) {
        showError();
        return;
      }
      let suffix = name.value.substring(name.value.lastIndexOf(".") + 1);

      let canPreviewType = ['txt', 'xls', 'xlsx', 'pdf', 'doc', 'docx', 'xbm', 'tif', 'pjp', 'svgz', 'jpg', 'jpeg', 'ico', 'tiff', 'gif', 'svg', 'jfif', 'webp', 'png', 'bmp', 'pjpeg', 'avif'];
      if (!canPreviewType.includes(suffix)) {
        showError();
        return;
      }

      document.title = name.value + " - 预览";
      name.value += " - 预览";
      loading.value = true;

      type.value = suffix;

      if (type.value === 'xls') {
        readWorkbookFromRemoteFile();
      } else {
        loadFile(suffix);
      }
    });

    return {
      type,
      fileId,
      fileBlob,
      loading,
      name,
      txtDecode,
      excelData,
      maxIndex,
      changeTxtDecode,
      loadFile,
      showError,
      readWorkbookFromRemoteFile,
      getTable,
      renderedHandler,
      errorHandler
    };
  }
});
</script>



